package cn.xingchen.web;

public class IsCardNo {
    public static boolean isIdCard(String idCard){
        if(idCard == null || "".equals(idCard)){
            return false;
        }
        if(idCard.length()==15){
            return false;
        }
        //定义 叛别用户 身份证号的正则表达式 （15位 或 18位，最后一位可以为字母）
        String requal = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|(10|20|30|31))\\d{3}[0-9Xx]$)|"
                +"(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";


        boolean matches = idCard.matches(requal);

        //判断 第 18位 校验值 ，校验算法涉及两次mod 11的过程
        // 二代身份证中的 号码第十八位的计算方法为：
        if(matches){
            if (idCard.length() == 18){
                try {
                    char[] charArray = idCard.toCharArray();
                    //1，将前面的身份证号码17位数分别乘以不同的系数，系数为此处的 加权因子
                    //前十七位加权因子
                    int[] idCardWi = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
                    int sum =  0;
                    // 2，将这17位数字 和系数相乘 的结果相加
                    for (int i = 0;i < idCardWi.length;i++){
                        int current = Integer.parseInt(String.valueOf(charArray[i]));
                        // 相乘对应的 加权因子系数
                        int count = current * idCardWi[i];
                        // 结果相加
                        sum += count;
                    }
                    char idCardLast = charArray[17];
                    // 3，结果和 除以11，查看余数
                    int idCardMod = sum % 11;
                    // 4，这是除以 11后，可能产生的 11位余数对应的验证码(--对应下标)，其中 X 代表罗马数字 10
                    String[] idCardY = {"1","0","X","9","8","7","6","5","4","3","2"};
                    if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())){
                        return true;
                    }else {
                        return false;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("异常："+idCard);
                    return false;
                }
            }
        }
        return matches;
    }

    public static void main(String[] args) {

        System.out.println(isIdCard("350112198910081945"));
        System.out.println(isIdCard("54090119760311922X"));
        System.out.println(isIdCard("050112198910081945"));
        System.out.println(isIdCard("130503670401001"));
        System.out.println(isIdCard("330103199110251022"));
        System.out.println(isIdCard("411612199309266925"));
        System.out.println(isIdCard("411627199309266925"));

        System.out.println(isIdCard("320822199809120080"));
        System.out.println(isIdCard("332624199311245439"));
        System.out.println(isIdCard("330219197211094481"));
        System.out.println(isIdCard("411282199306180512"));
        System.out.println(isIdCard("330103199110251022"));
        System.out.println(isIdCard("330103193610241042"));
        System.out.println(isIdCard("411612199309266925"));

    }


}